package xin.examinationSystem.servlet;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.metadata.CellExtra;
import com.alibaba.fastjson.JSON;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import xin.examinationSystem.account.testPaper.excelTopic.*;
import xin.examinationSystem.account.testPaper.topic.*;
import xin.examinationSystem.dao.ITeacherMapper;
import xin.examinationSystem.dao.topic.ITestPaperMapper;
import xin.examinationSystem.utils.ExcelTools;
import xin.examinationSystem.utils.Tools;

import java.util.ArrayList;
import java.util.List;

// 有个很重要的点 DemoDataListener 不能被spring管理，要每次读取excel都要new,然后里面用到spring可以构造方法传进去
public class DataListener extends AnalysisEventListener<ExcelClass> {
    private static final Logger LOGGER = LoggerFactory.getLogger(DataListener.class);
    /**
     * 每隔5条存储数据库，实际使用中可以3000条，然后清理list ，方便内存回收
     */
    private static final int BATCH_COUNT = 5;
    private static final ITestPaperMapper iTestPaperMapper = (ITestPaperMapper) Tools.getImp("ITestPaperMapper");
    List<ExcelClass> list = new ArrayList<ExcelClass>();
    TopicId topicId = TopicId.NULL;

    /**
     * 假设这个是一个DAO，当然有业务逻辑这个也可以是一个service。当然如果不用存储这个对象没用。
     */
    private ExcelClass demoDAO;

    /**
     * 如果使用了spring,请使用这个构造方法。每次创建Listener的时候需要把spring管理的类传进来
     *
     * @param demoDAO
     */
    public DataListener(ExcelClass demoDAO, TopicId t) {
        this.demoDAO = demoDAO;
        topicId = t;
    }


    @Override
    public void onException(Exception exception, AnalysisContext context) throws Exception {
        super.onException(exception, context);
    }

    @Override
    public void invoke(ExcelClass excelClass, AnalysisContext analysisContext) {
        list.add(excelClass);

        // 达到BATCH_COUNT了，需要去存储一次数据库，防止数据几万条数据在内存，容易OOM
        if (list.size() >= BATCH_COUNT) {
            saveData();
            list.clear();
        }
    }

    @Override
    public void extra(CellExtra extra, AnalysisContext context) {
        super.extra(extra, context);
    }

    /**
     * 所有数据解析完成了 都会来调用
     *
     * @param context
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        // 这里也要保存数据，确保最后遗留的数据也存储到数据库
        saveData();
        LOGGER.info("所有数据解析完成！");
    }

    @Override
    public boolean hasNext(AnalysisContext context) {
        return super.hasNext(context);
    }

    /**
     * 加上存储数据库
     */
    private void saveData() {
        ExcelClass ec = new ExcelClass();
        if (topicId == TopicId.SingleChoiceExcel) {
            for (ExcelClass excelClass : list) {
                SingleChoiceExcel sc = (SingleChoiceExcel) excelClass;
                iTestPaperMapper.addSingleChoice(new SingleChoice(sc.getTopic(), ExcelTools.numberTransitionChar(sc.getAnswer()),
                        "A．" + sc.getOption_A() + "###B．" + sc.getOption_B() + "###C．" + sc.getOption_C() + "###D．" + sc.getOption_D()));
            }
        } else if (topicId == TopicId.MultipleChoiceQuestionExcel) {
            for (ExcelClass excelClass : list) {
                MultipleChoiceQuestionExcel mcq = (MultipleChoiceQuestionExcel) excelClass;
                iTestPaperMapper.addMultipleChoiceQuestion(new MultipleChoiceQuestion(mcq.getTopic(), mcq.getAnswer().toLowerCase(),
                        "A．" + mcq.getOption_A() + "###B．" + mcq.getOption_B() + "###C．" + mcq.getOption_C() + "###D．" + mcq.getOption_D()));
            }
        } else if (topicId == TopicId.JudgeQuestionExcel) {
            for (ExcelClass excelClass : list) {
                JudgeQuestionExcel jq = (JudgeQuestionExcel) excelClass;
                iTestPaperMapper.addJudgeQuestion(new JudgeQuestion(jq.getTopic(), jq.getAnswer()));
            }
        } else if (topicId == TopicId.GapFillingExcel) {
            for (ExcelClass excelClass : list) {
                GapFillingExcel gf = (GapFillingExcel) excelClass;
                iTestPaperMapper.addGapFilling(new GapFilling(gf.getTopic()));
            }
        } else if (topicId == TopicId.EssayQuestionExcel) {
            for (ExcelClass excelClass : list) {
                EssayQuestionExcel eq = (EssayQuestionExcel) excelClass;
                System.out.println("写入:" + excelClass);
                iTestPaperMapper.addEssayQuestion(new EssayQuestion(eq.getTopic()));
            }
        }
    }
}